<template>
	<div class="data-reflux">
		<!-- 数据列表 -->
		<div class="search-box">
			<div class="left-search">
				<a-tree-select
					v-model:value="cameraTreeList"
					style="margin-right: 12px"
					:tree-data="cameraTreeData"
					:dropdown-match-select-width="dropdownMatchSelectWidth"
					class="select-item"
					:class="[cameraTreeList.length && 'active']"
					max-tag-count="responsive"
					allow-clear
					tree-checkable
					:field-names="{
						children: 'children',
						label: 'name',
						value: 'id'
					}"
					tree-node-filter-prop="name"
					:show-checked-strategy="SHOW_PARENT"
					placeholder="场景区域/摄像头"
					@change="changeCameraTreeList"
				></a-tree-select>
				<div class="time-part">
					<ul class="select-list">
						<li
							:key="item.value"
							v-for="(item, index) in presetTime"
							class="select-list-item"
							:class="[activeTimeIndex === index && 'active']"
							@click="changeTime(index, item.value)"
						>
							{{ item.text }}
						</li>
					</ul>
					<a-range-picker
						format="YYYY-MM-DD HH:mm"
						class="range-picker"
						value-format="YYYY-MM-DD HH:mm"
						:value="[startTime, endTime]"
						show-time
						:class="[startTime && 'active']"
						:placeholder="['开始时间', '结束时间']"
						input-read-only
						@calendar-change="changeRangePicker"
					>
						<template #suffixIcon> <clock-circle-outlined></clock-circle-outlined></template
					></a-range-picker>
				</div>
			</div>
			<div class="reset" @click="reset">
				<div>
					<global-svg-icon icon-name="reset" style="margin-right: 10px" width="14px" height="14px"></global-svg-icon>
					重置
				</div>
			</div>
		</div>
		<div class="content" tabindex="0" @blur="cardBlur">
			<vue-scroll @handle-scroll="handlePageScroll">
				<a-spin size="large" :spinning="tableAttr.loading" class="loading">
					<div v-if="tableAttr.data?.length === 0" style="display: flex; justify-content: center; padding-top: 160px">
						<global-svg-icon icon-name="empty" width="200px" height="72px" style="color: #4e596a"></global-svg-icon>
					</div>
					<div class="card-list">
						<div
							:key="item.id"
							v-for="(item, index) in tableAttr.data"
							:class="['card-list-item', cardSelectId === item.id && 'select', { lastLine: (index + 1) % 8 == 0 }]"
						>
							<div class="img-wrap" @click="previewData(index)">
								<img
									class="lazyload"
									:src="item.firstFrameImageUrl || defaultImage"
									:onerror="
										(e: any) => {
											e.target.src = defaultImage;
											e.target.onerror = null;
										}
									"
								/>
							</div>
							<div class="info-box">
								<div class="ai-item">
									<div class="title-time">{{ item.startTime }}至{{ item.endTime }}</div>
								</div>
								<div class="info-item mt4">
									<global-svg-icon
										icon-name="location"
										width="12px"
										height="12px"
										style="margin-right: 4px; vertical-align: baseline"
									></global-svg-icon>
									{{ item.areaLinkName }}
								</div>
								<div class="info-item">
									<global-svg-icon
										icon-name="camera-fill"
										width="12px"
										height="12px"
										style="margin-right: 4px; vertical-align: baseline"
									></global-svg-icon>
									{{ item.deviceName }}
								</div>
							</div>
						</div>
					</div>
				</a-spin>
			</vue-scroll>
		</div>

		<div class="pagination">
			<global-pagination
				:current="tableAttr.current"
				:page-size="tableAttr.pageSize"
				:total="tableAttr.total"
				:page-size-options="['50', '100', '200']"
				@change="onPaginationChange"
			></global-pagination>
		</div>

		<preview-video ref="previewVideoRef" @toggle="(id) => (cardSelectId = id)"></preview-video>
	</div>
</template>

<script lang="ts" setup>
import PreviewVideo from './PreviewVideo.vue';
import { TreeSelect } from 'ant-design-vue';
import { g6UseTable } from 'glasssix-vue3-hooks';
import { DataRefluxApi } from '../../api';
import { arr2Str } from '@/global-utils/base.utils';
import defaultImage from '@/global-assets/imgs/img-none.png';
import dayjs from 'dayjs';

const cameraTreeList = ref([]);
const cameraTreeData = ref<any>([]);

const dropdownMatchSelectWidth = ref<number>(500);
const mAreaIdList = ref<any>([]);
const areDeviceIdList = ref<string[]>([]);
const previewVideoRef = ref();
const SHOW_PARENT = TreeSelect.SHOW_PARENT;

const { tableAttr, setTableData, setTablePagination } = g6UseTable(DataRefluxApi.list, { pageSize: 50 });

// interface DataItem {
// 	firstFrameImageUrl: string;
// 	videoUrl: string;
// 	startTime: string;
// 	endTime: string;
// 	deviceId: string | number | null;
// 	deviceName: string;
// 	areaId: string | number | null;
// 	areaLinkName: string;
// 	createTime: string;
// 	id: number | string;
// 	[key: string]: any;
// }

// 预设时间段
const presetTime = ref<any>([
	{
		text: '今日',
		value: 1
	},
	{
		text: '近7天',
		value: 7
	},
	{
		text: '近30天',
		value: 30
	}
]);

const activeTimeIndex = ref<number>(0);
const headerBottomBorderColor = ref('transparent');

const handlePageScroll = (vertical: Record<string, any>): void => {
	headerBottomBorderColor.value = vertical.scrollTop > 10 ? '#20305b' : 'transparent';
};
// ===================卡片选中===================
const cardSelectId = ref<number | null>(null);

// 失去焦点 清空选中
const cardBlur = () => {
	if (!previewVideoRef.value.getVisible()) {
		cardSelectId.value = null;
	}
};
// ===================卡片选中 END===================
// 设备筛选不用禁用离线设备
const noDisableDevice = (tree: any[]) => {
	tree.forEach((node: { disabled: boolean; children: string | any[] }) => {
		node.disabled = false;
		if (node.children) {
			if (node.children.length > 0) {
				noDisableDevice(node.children as any[]);
			}
		}
	});
	return tree;
};

const getDeviceList = async (): Promise<void> => {
	let { data } = await DataRefluxApi.getDeviceList();
	cameraTreeData.value = noDisableDevice(data);
};
const previewData = (index: number) => {
	previewVideoRef.value?.openModal(tableAttr.data, index);
};

// 递归筛选
const findObjectById = (data: any, id: string): any => {
	for (let i = 0; i < data.length; i++) {
		const obj = data[i];
		if (obj.id === id) {
			return obj;
		}
		if (obj.children && obj.children.length > 0) {
			const result = findObjectById(obj.children, id);
			if (result) {
				return result;
			}
		}
	}
	return null;
};
const flatten = (data: any): any => {
	return data.reduce((prev: any, cur: any) => {
		prev.push({ areaOrDeviceId: cur.areaOrDeviceId, name: cur.name });
		if (cur.children) {
			prev.push(...flatten(cur.children));
		}
		return prev;
	}, []);
};

// 查询
const handleSearch = (key?: string): void => {
	console.log(key);
	switch (key) {
		case 'mAreaOrDeviceIdList':
			tableAttr.searchObj.mAreaIdList = arr2Str(mAreaIdList.value);
			tableAttr.searchObj.areDeviceIdList = arr2Str(areDeviceIdList.value);
			console.log('mAreaIdList.value:', mAreaIdList.value, 'areDeviceIdList.value:', areDeviceIdList.value);

			break;
		default:
			break;
	}
	setTableData(true);
};
// 场景区域/摄像头的值改变时
const changeCameraTreeList = (value: any): void => {
	mAreaIdList.value = [];
	areDeviceIdList.value = [];

	value.forEach((item: any) => {
		const re = findObjectById(cameraTreeData.value, item);

		// type为1时代表选择区域,则把区域id和摄像头id都传入
		if (re.type === 1) {
			console.log('re:', re);

			const flatData = flatten(re.children ? re.children : [re]);
			if (re.children) {
				flatData.forEach((i: any) => {
					areDeviceIdList.value.push(i.areaOrDeviceId);
				});
			}
			mAreaIdList.value.push(re.areaOrDeviceId);
		}
		// type为0时代表选择摄像头，只传摄像头id
		if (re.type === 0) {
			areDeviceIdList.value.push(re.areaOrDeviceId);
		}
	});

	handleSearch('mAreaOrDeviceIdList');
};
/* ------------------- 处理时间选择逻辑 ------------------ */
// 时间过滤
const startTime = ref<any>();
const endTime = ref<any>();
// 根据传入的天数，获取以当前时间基准的时间范围
const GetTimeRange = (day: number, init: boolean = true): void => {
	const createBegin = dayjs()
		.subtract(day - 1, 'days')
		.startOf('day')
		.format('YYYY-MM-DD HH:mm:ss');
	const createEnd = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss');

	tableAttr.searchObj.startTime = createBegin;
	tableAttr.searchObj.endTime = createEnd;
	startTime.value = undefined;
	endTime.value = undefined;
	tableAttr.current = 1;
	if (init) {
		handleSearch();
	}
};
const changeRangePicker = (dates: any, date: string[]): void => {
	activeTimeIndex.value = -1;
	if (date && date.length) {
		if (date[0] !== '') {
			tableAttr.searchObj.startTime = `${date[0]}:00`;

			startTime.value = `${date[0]}`;
		}
		if (date[1] !== '') {
			tableAttr.searchObj.endTime = `${date[1]}:59`;
			endTime.value = `${date[1]}`;
		}
		if (date[0] === '' && date[1] === '') {
			activeTimeIndex.value = 0;
			GetTimeRange(7);

			tableAttr.searchObj.startTime = undefined;
			tableAttr.searchObj.endTime = undefined;
			startTime.value = undefined;
			endTime.value = undefined;
		}

		tableAttr.current = 1;
		handleSearch();
	}
};
const changeTime = (index: number, day: number): void => {
	// 如果是同一天不搜索
	if (index === activeTimeIndex.value) {
		return;
	}
	activeTimeIndex.value = index;

	GetTimeRange(day);
};
// 分页处理
const onPaginationChange = (page: number, pageSize: number): void => {
	// 重置被选项
	document.querySelector('.card-wrap')?.scrollTo(0, 0);
	setTablePagination(page, pageSize);
};

const reset = () => {
	if (tableAttr.loading) {
		return;
	}
	tableAttr.searchObj = {};
	cameraTreeList.value = [];
	activeTimeIndex.value = 0;
	GetTimeRange(1, false);
	setTableData(true);
};

onMounted(() => {
	GetTimeRange(1, false);
	getDeviceList();
	setTableData();
});
</script>

<style lang="less" scoped>
.data-reflux {
	position: relative;
	color: @text01;
}

.search-box {
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: 36px;
	padding: 0 32px;

	.left-search {
		display: flex;
		align-items: center;

		.select-item {
			width: 180px;

			&.active {
				width: 285px;
			}
		}

		.time-part {
			display: flex;

			.select-list {
				display: flex;
				// width: 280px;
				height: 36px;
				margin: 0 8px 0 0;
				border: 1px solid @mask02;
				border-radius: 6px;
				padding: 3px 0;
				font-size: 14px;
				line-height: 22px;
				color: @text02;
				flex-shrink: 0;

				.select-list-item {
					position: relative;
					width: 87px;
					margin: 0 3px;
					border-radius: 4px;
					padding: 3px 0;
					text-align: center;
					// line-height: 36px;
					cursor: pointer;

					&.active {
						color: @text01;
						background: @primary01;

						&:hover {
							background: @primary02 !important;
						}

						&:active {
							background: @primary03 !important;
						}
					}
					// 分割线
					&::after {
						position: absolute;
						top: 50%;
						right: -6px;
						width: 1px;
						height: 14px;
						margin-right: 3px;
						background: @borderColor02;
						transform: translateY(-50%);
						content: '';
					}

					&:last-child {
						&::after {
							display: none;
						}
					}
				}
			}

			.range-picker {
				width: 216px;
				flex-shrink: 0;

				svg {
					color: red;
				}

				&.active {
					width: 308px;
				}
			}
		}
	}

	.reset {
		display: flex;
		flex-direction: column;
		justify-content: center;
		color: @text03;
		cursor: pointer;
	}
}

.content {
	width: 100%;
	height: calc(100vh - 76px - 48px - 36px - 76px - 51px);
	padding-top: 20px;
	padding-left: 32px;
	outline: none;

	.card-list {
		display: grid;
		overflow: hidden !important;
		width: 100%;
		height: 100%;
		padding-right: 32px;
		padding-bottom: 20px;
		grid-template-columns: repeat(5, 1fr);
		grid-template-rows: repeat(2, 1fr);
		grid-column-gap: 8px;
		/* stylelint-disable-next-line declaration-block-no-redundant-longhand-properties */
		grid-row-gap: 8px;

		.lastLine {
			margin-right: 0;
		}

		.card-list-item {
			position: relative;
			min-width: 230px;
			max-width: 326px;
			border: 1px solid transparent;
			padding: 8px;
			cursor: pointer;

			.img-wrap {
				width: 100%;
				height: auto;
				min-height: 133px;
				max-height: 191px;

				> img {
					width: 100%;
					height: 100%;
					object-fit: cover;
					border-radius: 4px;
				}
			}

			.info-box {
				overflow: hidden; /* 隐藏超出容器的内容 */
				white-space: nowrap; /* 防止换行 */
				text-overflow: ellipsis; /* 当文字超出容器时显示省略号 */
				color: @text03;

				.ai-item {
					display: flex;
					margin-top: 6px;
					font-size: 12px;
					line-height: 20px;
					color: @text01;
					justify-content: space-between;

					.title-time {
						font-size: 14px;
						font-weight: 400;
						font-style: normal;
						line-height: 22px; /* 157.143% */
						text-align: center;
						color: @text01;
					}

					.ai-alarm-name {
						border-radius: 4px;
						padding: 0 6px;
						font-family: 'Alimama FangYuanTi VF';
						line-height: 20px;
						background: @secondary03;
						text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
					}

					.sence-name {
						line-height: 20px;
					}
				}

				.info-item {
					display: flex;
					line-height: 20px;
					color: @text03;
					align-items: center;
				}

				.mt4 {
					margin-top: 4px;
				}

				.time-item {
					margin-top: 4px;
					line-height: 20px;
					color: @text04;
				}
			}

			.tag {
				margin-left: auto;
				border: 1px solid rgba(0, 0, 0, 0.12);
				border-radius: 4px;
				padding: 0 6px;
				font-size: 12px;
				white-space: nowrap;
				color: #d67900;
				background: rgba(245, 151, 0, 0.12);
			}

			&.select {
				border: 1px solid #3d7fe9;
				border-radius: 6px;
				background: rgba(26, 111, 243, 0.4);
			}

			&:hover,
			&.checked {
				border: 1px solid #374b79;
				border-radius: 8px;
				background: radial-gradient(66.29% 107.13% at 0% 0%, rgba(38, 62, 131, 0.12) 0%, rgba(217, 217, 217, 0.02) 100%), #0f224e;
				box-shadow: 0 3px 16px 0 rgba(0, 0, 0, 0.25);
			}
		}
	}
}

.pagination {
	display: flex;
	width: 100%;
	height: 48px;
	border-radius: 0 0 8px 8px;
	padding: 0 24px;
	color: #f0f6fc;
	background: @background02;
	box-shadow: 0 -1px 8px 0 rgba(0, 0, 0, 0.25);
	justify-content: center;
	align-items: center;
}
</style>
